/**
 * 
 */
package primeFinder;

/**
 * @author mfan
 *
 */
public abstract class AbstractPrimeFinder {

	/**
	 * Test: is given parameter "number" a prime or not
	 * 
	 * @param number
	 * @return: true--given parameter "number" is a prime, false--given parameter "number" is not a prime
	 */
	private boolean isPrime (final long number) {
		
		if (number <= 1) {
			return false;
		}
		
		for (int i = 2; i <= Math.sqrt(number); i++) {
			if ((number % i) == 0) {
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * Count number of primes in a given range
	 * 
	 * @param low
	 * @param high
	 * @return
	 */
	protected long countPrimesInRange (final long low, final long high) {
		
		long returnValue = 0;
		
		for (long i = low; i < high; i++) {
			if (isPrime(i)) {
				returnValue ++;
			}
		}
		
		return returnValue;
	}
	
	/**
	 * @param high
	 */
	public void computeAndGetTiming (final long high) {
		
		System.out.printf("Start counting primes between 2 ~ %d....%n", high);
		final long start = System.nanoTime();
		final long primeCount =  countPrime(high);
		final long end = System.nanoTime();
		
		System.out.printf("There are %d primes between 2 ~ %d.%n", primeCount, high);
		System.out.printf("It spents %f seconds to reach the result.", (end - start)/1.0e9);
	}
	
	//
	protected abstract long countPrime (final long high);
	
}
